home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 7
/
Night Owl Shareware (NOPV7)(Night Owl Publisher Inc.)(1992).bin
/
038a
/
bash1_12.arj
/
BASH1-12.TAR
/
bash-1.12
/
builtins
/
set.def
< prev
next >
Wrap
Text File
|
1991-12-29
|
13KB
|
486 lines
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES set.c
#include <stdio.h>
#include "../shell.h"
#include "../flags.h"
extern int interactive;
$BUILTIN set
$FUNCTION set_builtin
$SHORT_DOC set [-abefhknotuvxldH] [arg ...]
-a Mark variables which are modified or created for export
-b Notify of job termination immediately
-e Exit immediately if a command exits with a non-zero status
-f Disable file name generation (globbing)
-h Locate and remember function commands as functions are
defined. Function commands are normally looked up when
the function is executed
-k All keyword arguments are placed in the environment for a
command, not just those that precede the command name
-m Job control is enabled
-n Read commands but do not execute them
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand the shell will perform brace expansion
emacs use an emacs-style line editing interface
errexit same as -e
histexpand same as -H
ignoreeof the shell will not exit upon reading EOF
monitor same as -m
noclobber disallow redirection to existing files
noexec same as -n
noglob same as -f
nohash same as -d
notify save as -b
nounset same as -u
verbose same as -v
vi use a vi-style line editing interface
xtrace same as -x
-t Exit after reading and executing one command
-u Treat unset variables as an error when substituting
-v Print shell input lines as they are read
-x Print commands and their arguments as they are executed
-l Save and restore the binding of the NAME in a FOR command.
-d Disable the hashing of commands that are looked up for execution.
Normally, commands are remembered in a hash table, and once
found, do not have to be looked up again
-H Enable ! style history substitution. This flag is on
by default.
-C If set, disallow existing regular files to be overwritten
by redirection of output.
Using + rather than - causes these flags to be turned off. The
flags can also be used upon invocation of the shell. The current
set of flags may be found in $-. The remaining ARGs are positional
parameters and are assigned, in order, to $1, $2, .. $9. If no
ARGs are given, all shell variables are printed.
$END
/* An a-list used to match long options for set -o to the corresponding
option letter. */
struct {
char *name;
int letter;
} o_options[] = {
{ "allexport", 'a' },
{ "errexit", 'e' },
{ "histexpand", 'H' },
{ "monitor", 'm' },
{ "noexec", 'n' },
{ "noglob", 'f' },
{ "nohash", 'd' },
#if defined (JOB_CONTROL)
{ "notify", 'b' },
#endif /* JOB_CONTROL */
{"nounset", 'u' },
{"verbose", 'v' },
{"xtrace", 'x' },
{(char *)NULL, 0},
};
static void
list_long_opts ()
{
register int i;
char *on = "on", *off = "off";
extern int noclobber, no_brace_expansion;
extern SHELL_VAR *find_variable ();
#if defined (READLINE)
extern int rl_editing_mode, no_line_editing;
#endif /* READLINE */
printf ("%-15s\t%s\n", "braceexpand", (no_brace_expansion == 0) ? on : off);
printf ("%-15s\t%s\n", "noclobber", (noclobber == 1) ? on : off);
if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
printf ("%-15s\t%s\n", "ignoreeof", on);
else
printf ("%-15s\t%s\n", "ignoreeof", off);
#if defined (READLINE)
if (no_line_editing)
{
printf ("%-15s\toff\n", "emacs");
printf ("%-15s\toff\n", "vi");
}
else
{
/* Magic. This code `knows' how readline handles rl_editing_mode. */
printf ("%-15s\t%s\n", "emacs", (rl_editing_mode == 1) ? on : off);
printf ("%-15s\t%s\n", "vi", (rl_editing_mode == 0) ? on : off);
}
#endif /* READLINE */
for (i = 0; o_options[i].name; i++)
{
int *on_or_off, zero = 0;
char name[2];
name[0] = o_options[i].letter;
name[1] = '\0';
on_or_off = find_flag (name);
if (on_or_off == (int *)FLAG_ERROR)
on_or_off = &zero;
printf ("%-15s\t%s\n", o_options[i].name, (*on_or_off == 1) ? on : off);
}
}
set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
{
extern int no_brace_expansion;
int option_char = -1;
if (strcmp (option_name, "braceexpand") == 0)
{
if (on_or_off == FLAG_ON)
no_brace_expansion = 0;
else
no_brace_expansion = 1;
}
else if (strcmp (option_name, "noclobber") == 0)
{
if (on_or_off == FLAG_ON)
bind_variable ("noclobber", "");
else
unbind_variable ("noclobber");
stupidly_hack_special_variables ("noclobber");
}
else if (strcmp (option_name, "ignoreeof") == 0)
{
unbind_variable ("ignoreeof");
unbind_variable ("IGNOREEOF");
if (on_or_off == FLAG_ON)
bind_variable ("IGNOREEOF", "10");
stupidly_hack_special_variables ("IGNOREEOF");
}
#if defined (READLINE)
else if ((strcmp (option_name, "emacs") == 0) ||
(strcmp (option_name, "vi") == 0))
{
extern int no_line_editing;
if (on_or_off == FLAG_ON)
{
rl_variable_bind ("editing-mode", option_name);
if (interactive)
with_input_from_stdin ();
no_line_editing = 0;
}
else
{
extern int rl_editing_mode;
int isemacs = (rl_editing_mode == 1);
if ((isemacs && strcmp (option_name, "emacs") == 0) ||
(!isemacs && strcmp (option_name, "vi") == 0))
{
if (interactive)
with_input_from_stream (stdin, "stdin");
no_line_editing = 1;
}
else
builtin_error ("not in %s editing mode",
option_name);
}
}
#endif /* READLINE */
else
{
register int i;
for (i = 0; o_options[i].name; i++)
{
if (strcmp (option_name, o_options[i].name) == 0)
{
option_char = o_options[i].letter;
break;
}
}
if (option_char == -1)
{
builtin_error ("%s: unknown option name", option_name);
return (EXECUTION_FAILURE);
}
if (change_flag_char (option_char, on_or_off) == FLAG_ERROR)
{
bad_option (option_name);
return (EXECUTION_FAILURE);
}
}
return (EXECUTION_SUCCESS);
}
/* Set some flags from the word values in the input list. If LIST is empty,
then print out the values of the variables instead. If LIST contains
non-flags, then set $1 - $9 to the successive words of LIST. */
set_builtin (list)
WORD_LIST *list;
{
int on_or_off, flag_name, force_assignment = 0;
if (!list)
{
SHELL_VAR **vars;
vars = all_shell_variables ();
if (vars)
{
print_var_list (vars);
free (vars);
}
vars = all_shell_functions ();
if (vars)
{
print_var_list (vars);
free (vars);
}
return (EXECUTION_SUCCESS);
}
/* Check validity of flag arguments. */
if (*list->word->word == '-' || *list->word->word == '+')
{
register char *arg;
WORD_LIST *save_list = list;
while (list && (arg = list->word->word))
{
char s[2];
if (arg[0] != '-' && arg[0] != '+')
break;
/* `-' or `--' signifies end of flag arguments. */
if (arg[0] == '-' &&
(!arg[1] || (arg[1] == '-' && !arg[2])))
break;
s[1] = '\0';
while (s[0] = *++arg)
{
if (find_flag (s) == (int *)FLAG_ERROR && s[0] != 'o')
{
bad_option (s);
return (EXECUTION_FAILURE);
}
}
list = list->next;
}
list = save_list;
}
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$1 ... $n. */
while (list)
{
char *string = list->word->word;
/* If the argument is `--' then signal the end of the list and
remember the remaining arguments. */
if ((strcmp (string, "--") == 0) || (strcmp (string, "-") == 0))
{
list = list->next;
/* `set --' unsets the positional parameters. */
if (strcmp (string, "--") == 0)
force_assignment = 1;
/* Until told differently, the old shell behaviour of
`set - [arg ...]' being equivalent to `set +xv [arg ...]'
stands. Posix.2 says the behaviour is marked as obsolescent. */
else
{
change_flag_char ('x', '+');
change_flag_char ('v', '+');
}
break;
}
if ((on_or_off = *string) &&
(on_or_off == '-' || on_or_off == '+'))
{
int i = 1;
while (flag_name = string[i++])
{
if (flag_name == '?')
{
/* Print all the possible flags. */
}
else if (flag_name == 'o') /* -+o option-name */
{
char *option_name;
WORD_LIST *opt;
opt = list->next;
if (!opt)
{
list_long_opts ();
continue;
}
option_name = opt->word->word;
if (!option_name || !*option_name || (*option_name == '-'))
{
list_long_opts ();
continue;
}
list = list->next; /* Skip over option name. */
if (set_minus_o_option
(on_or_off, option_name) != EXECUTION_SUCCESS)
return (EXECUTION_FAILURE);
}
else
{
if (change_flag_char (flag_name, on_or_off) == FLAG_ERROR)
{
char opt[3];
opt[0] = on_or_off;
opt[1] = flag_name;
opt[2] = '\0';
bad_option (opt);
return (EXECUTION_FAILURE);
}
}
}
}
else
{
break;
}
list = list->next;
}
/* Assigning $1 ... $n */
if (list || force_assignment)
remember_args (list, 1);
return (EXECUTION_SUCCESS);
}
$BUILTIN unset
$FUNCTION unset_builtin
$SHORT_DOC unset [-f] [-v] [name ...]
For each NAME, remove the corresponding variable or function. Given
the `-v', unset will only act on variables. Given the `-f' flag,
unset will only act on functions. With neither flag, unset first
tries to unset a variable, and if that fails, then tries to unset a
function. Some variables (such as PATH and IFS) cannot be unset; also
see readonly.
$END
unset_builtin (list)
WORD_LIST *list;
{
extern char **non_unsettable_vars;
int unset_function = 0, unset_variable = 0;
int any_failed = 0;
char *name;
while (list)
{
name = list->word->word;
if (strcmp (name, "-f") == 0)
{
list = list->next;
unset_function++;
continue;
}
if (strcmp (name, "-v") == 0)
{
list = list->next;
unset_variable++;
continue;
}
else if (strcmp (name, "--") == 0)
{
list = list->next;
break;
}
else if (*name == '-')
{
bad_option (name);
return (EXECUTION_FAILURE);
}
else
break;
}
if (unset_function && unset_variable)
{
builtin_error ("cannot simultaneously unset a function and a variable");
return (EXECUTION_FAILURE);
}
while (list)
{
name = list->word->word;
if (!unset_function &&
find_name_in_list (name, non_unsettable_vars) > -1)
{
builtin_error ("%s: cannot unset", name);
any_failed++;
}
else
{
/* Unless the -f option is supplied, the name refers to a
variable. */
int tem = makunbound (name,
unset_function ? shell_functions : shell_variables);
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
is specified, the name refers to a variable; if a variable by
that name does not exist, a function by that name, if any,
shall be unset.'' */
if ((tem == -1) && !unset_function && !unset_variable)
tem = makunbound (name, shell_functions);
if (tem == -1)
any_failed++;
else if (!unset_function)
stupidly_hack_special_variables (name);
}
list = list->next;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}